package com.netty.server;

import com.alibaba.fastjson2.JSON;
import com.netty.msg.Message;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
    private static final Logger log = LoggerFactory.getLogger(NettyServerHandler.class);


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {
        log.info("接收到消息:{}", msg);
        try {
            Message message = JSON.parseObject(msg, Message.class);
            //对message 处理业务
            Message rsp = new Message();
            rsp.setCommand("rsp");
            rsp.setData("this is server response,now:" + System.currentTimeMillis());
            String rspMsg = JSON.toJSONString(rsp);
            channelHandlerContext.writeAndFlush(rspMsg).addListener(new GenericFutureListener<Future<? super Void>>() {
                @Override
                public void operationComplete(Future<? super Void> future) throws Exception {
                    if (future.isSuccess()) {
                        log.info("服务端-消息发送成功");
                    } else {
                        log.error("服务端-消息发送失败", future.cause());
                    }
                }
            });;
        } catch (Exception e) {
            log.error("处理消息:{}失败,详细:{}", msg, e.getMessage());
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 获取客户端的远程地址
        Channel channel = ctx.channel();
        String remoteAddress = channel.remoteAddress().toString();
        ClientConnectData.channels.add(channel);
        // 在这里添加你的验证逻辑
        if (isClientAllowed(remoteAddress)) {
            log.info("Client " + remoteAddress + " is allowed to connect.");
            // 继续处理正常的业务逻辑
            super.channelActive(ctx);
        } else {
            log.warn("Client " + remoteAddress + " is not allowed to connect. Closing the connection.");
            // 如果客户端不允许连接，则关闭该连接
            closeClient(ctx);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String remoteAddress = channel.remoteAddress().toString();
        log.info("Client " + remoteAddress + " disconnect.");
        super.channelInactive(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                // 读空闲事件，表示一段时间内没有从客户端接收到数据
                log.warn("Idle read, closing the connection: " + ctx.channel().remoteAddress());
                // 关闭连接
                closeClient(ctx);
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }

    private boolean isClientAllowed(String remoteAddress) {
        return true;
    }

    void closeClient(ChannelHandlerContext ctx) {
        ChannelFuture closeChannelFuture = ctx.close();
    }
}
